/**
 * 通知服务类 - 处理浏览器通知权限和推送
 */
class NotificationService {
  constructor() {
    this.isSupported = 'Notification' in window;
    this.permission = this.isSupported ? Notification.permission : 'unsupported';
    this.reminders = this.loadReminders();
    this.setupNotificationListeners();
  }

  /**
   * 请求通知权限
   * @returns {Promise<boolean>} 是否获得权限
   */
  async requestPermission() {
    if (!this.isSupported) {
      console.warn('浏览器不支持通知功能');
      return false;
    }

    try {
      const permission = await Notification.requestPermission();
      this.permission = permission;
      return permission === 'granted';
    } catch (error) {
      console.error('请求通知权限失败:', error);
      return false;
    }
  }

  /**
   * 检查权限状态
   * @returns {boolean} 是否已获得权限
   */
  hasPermission() {
    return this.permission === 'granted';
  }

  /**
   * 发送即时通知
   * @param {string} title 通知标题
   * @param {Object} options 通知选项
   */
  sendNotification(title, options = {}) {
    if (!this.hasPermission()) {
      console.warn('没有通知权限');
      return null;
    }

    const notificationOptions = {
      body: '',
      icon: '/moon-icon.svg', // 假设项目中有这个图标
      badge: '/star-icon.svg', // 假设项目中有这个图标
      vibrate: [200, 100, 200],
      ...options
    };

    try {
      const notification = new Notification(title, notificationOptions);
      
      // 设置通知点击事件
      if (options.onClick) {
        notification.onclick = options.onClick;
      }
      
      return notification;
    } catch (error) {
      console.error('发送通知失败:', error);
      return null;
    }
  }

  /**
   * 为天文事件设置提醒
   * @param {Object} event 天文事件对象
   * @param {number} minutesBefore 提前多少分钟提醒
   */
  setEventReminder(event, minutesBefore = 60) {
    const eventDate = new Date(event.date);
    const reminderTime = new Date(eventDate.getTime() - minutesBefore * 60 * 1000);
    
    // 计算延迟时间
    const delay = reminderTime.getTime() - Date.now();
    
    // 如果已经过了提醒时间，则不设置
    if (delay <= 0) {
      console.warn('提醒时间已过');
      return null;
    }

    // 创建提醒对象
    const reminder = {
      id: Date.now().toString(),
      eventId: event.id,
      eventTitle: event.title,
      eventDate: event.date,
      reminderTime: reminderTime.toISOString(),
      minutesBefore,
      timeoutId: setTimeout(() => {
        this.sendNotification(`天文事件提醒: ${event.title}`, {
          body: `${event.title} 将在 ${minutesBefore} 分钟后开始。${event.description || ''}`,
          onClick: () => {
            // 点击通知时打开对应事件的页面
            window.focus();
            // 这里可以添加导航到事件详情的逻辑
          }
        });
        
        // 移除已触发的提醒
        this.removeReminder(reminder.id);
      }, delay)
    };

    // 保存提醒
    this.reminders.push(reminder);
    this.saveReminders();
    
    return reminder.id;
  }

  /**
   * 移除提醒
   * @param {string} reminderId 提醒ID
   */
  removeReminder(reminderId) {
    const reminder = this.reminders.find(r => r.id === reminderId);
    if (reminder && reminder.timeoutId) {
      clearTimeout(reminder.timeoutId);
    }
    
    this.reminders = this.reminders.filter(r => r.id !== reminderId);
    this.saveReminders();
  }

  /**
   * 获取所有提醒
   * @returns {Array} 提醒列表
   */
  getAllReminders() {
    return [...this.reminders];
  }

  /**
   * 获取某个事件的所有提醒
   * @param {string} eventId 事件ID
   * @returns {Array} 提醒列表
   */
  getEventReminders(eventId) {
    return this.reminders.filter(r => r.eventId === eventId);
  }

  /**
   * 保存提醒到本地存储
   */
  saveReminders() {
    // 不保存timeoutId，因为页面刷新后会失效
    const remindersToSave = this.reminders.map(r => ({
      id: r.id,
      eventId: r.eventId,
      eventTitle: r.eventTitle,
      eventDate: r.eventDate,
      reminderTime: r.reminderTime,
      minutesBefore: r.minutesBefore
    }));
    
    try {
      localStorage.setItem('astronomyEventReminders', JSON.stringify(remindersToSave));
    } catch (error) {
      console.error('保存提醒失败:', error);
    }
  }

  /**
   * 从本地存储加载提醒
   * @returns {Array} 提醒列表
   */
  loadReminders() {
    try {
      const saved = localStorage.getItem('astronomyEventReminders');
      if (saved) {
        const reminders = JSON.parse(saved);
        // 重新设置计时器
        return reminders.map(reminder => ({
          ...reminder,
          timeoutId: this.setupReminderTimer(reminder)
        }));
      }
    } catch (error) {
      console.error('加载提醒失败:', error);
    }
    return [];
  }

  /**
   * 为提醒设置计时器
   * @param {Object} reminder 提醒对象
   * @returns {number|null} timeout ID 或 null
   */
  setupReminderTimer(reminder) {
    const reminderTime = new Date(reminder.reminderTime);
    const delay = reminderTime.getTime() - Date.now();
    
    if (delay <= 0) {
      // 如果已经过了提醒时间，检查是否还在事件当天
      const eventDate = new Date(reminder.eventDate);
      const today = new Date();
      const isSameDay = eventDate.toDateString() === today.toDateString();
      
      if (!isSameDay) {
        // 如果不是事件当天，删除这个过期的提醒
        setTimeout(() => {
          this.removeReminder(reminder.id);
        }, 0);
      }
      
      return null;
    }

    return setTimeout(() => {
      this.sendNotification(`天文事件提醒: ${reminder.eventTitle}`, {
        body: `${reminder.eventTitle} 将在 ${reminder.minutesBefore} 分钟后开始。`,
        onClick: () => {
          window.focus();
          // 这里可以添加导航到事件详情的逻辑
        }
      });
      
      this.removeReminder(reminder.id);
    }, delay);
  }

  /**
   * 设置通知相关的监听器
   */
  setupNotificationListeners() {
    // 监听页面可见性变化
    document.addEventListener('visibilitychange', () => {
      if (!document.hidden && this.hasPermission()) {
        // 页面变为可见时，可以检查是否有错过的提醒
        this.checkMissedReminders();
      }
    });
  }

  /**
   * 检查是否有错过的提醒
   */
  checkMissedReminders() {
    const now = Date.now();
    const missedReminders = this.reminders.filter(reminder => {
      const reminderTime = new Date(reminder.reminderTime).getTime();
      return reminderTime <= now;
    });

    // 处理错过的提醒（例如显示一个汇总通知）
    if (missedReminders.length > 0) {
      this.sendNotification(
        `您有 ${missedReminders.length} 个错过的天文事件提醒`,
        {
          body: `查看您错过的天文事件`,
          onClick: () => {
            window.focus();
            // 导航到事件列表
          }
        }
      );

      // 移除这些已处理的过期提醒
      missedReminders.forEach(reminder => this.removeReminder(reminder.id));
    }
  }
}

// 导出单例实例
export default new NotificationService();